home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / OCFSRC.PAK / AUTOVAL.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  21KB  |  687 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectComponents
  3. // Copyright (c) 1994, 1997 by Borland International, All Rights Reserved
  4. //
  5. // $Revision:   2.16  $
  6. //
  7. // TAutoVal implementation
  8. //----------------------------------------------------------------------------
  9. #include <ocf/pch.h>
  10. #if !defined(OCF_AUTODEFS_H)
  11. # include <ocf/autodefs.h>
  12. #endif
  13. #if !defined(SERVICES_MEMORY_H)
  14. # include <services/memory.h>
  15. #endif
  16. #if !defined(CLASSLIB_POINTER_H)
  17. # include <classlib/pointer.h>
  18. #endif
  19. #if !defined(__LIMITS_H)
  20. # include <limits.h>
  21. #endif
  22.  
  23. //----------------------------------------------------------------------------
  24. // TAutoVal assignment operators (others are inline)
  25. //
  26.  
  27. //
  28. //
  29. void
  30. TAutoVal::operator =(TAutoString s)
  31. {
  32.   vt = atString;
  33.   bstrVal = ::SysAllocString((const OLECHAR far*)s);
  34.   SetLocale(s.GetLangId() ? s.GetLangId() : TLocaleString::NativeLangId);
  35. }
  36.  
  37. //
  38. //
  39. void
  40. TAutoVal::operator =(const string& s)
  41. {
  42.   vt = atString;
  43.   bstrVal = NS_CLASSLIB::SysAllocString(s.c_str());
  44.   SetLocale(TLocaleString::NativeLangId);
  45. }
  46.  
  47. //
  48. // should add operator==(TLocaleString) which translates to proper LangId
  49. // this requires Set/GetLocale to be used for atVoid initialized variants
  50. //
  51.  
  52. //----------------------------------------------------------------------------
  53. // TAutoVal conversion operators
  54. //
  55.  
  56. //
  57. //
  58. //
  59. void
  60. TAutoVal::SetLocale(TLocaleId locale)
  61. {
  62.   switch (vt) {
  63.     case atVoid:
  64.     case atString:
  65.     case atObject:
  66.          p.Locale = locale;
  67.   };
  68. }
  69.  
  70. //
  71. //
  72. //
  73. TLocaleId
  74. TAutoVal::GetLocale() const
  75. {
  76.   switch (vt) {
  77.     case atVoid:
  78.     case atString:
  79.     case atObject:
  80.         return p.Locale;
  81.   };
  82.   return 0;
  83. }
  84.  
  85. //
  86. //
  87. //
  88. TLangId
  89. TAutoVal::GetLanguage() const
  90. {
  91.   switch (vt) {
  92.     case atVoid:
  93.     case atString:
  94.     case atObject:
  95.       return LANGIDFROMLCID(p.Locale);
  96.   };
  97.   return 0;
  98. }
  99.  
  100. //
  101. //
  102. //
  103. TAutoVal::operator unsigned char()
  104. {
  105.   unsigned char v;
  106.   switch (vt) {
  107.   case atByte:    return bVal;
  108.   case atShort:   if(::VarUI1FromI2(iVal,  &v)) break; return v;
  109.   case atLong:    if(::VarUI1FromI4(lVal,  &v)) break; return v;
  110.   case atFloat:   if(::VarUI1FromR4(fltVal,&v)) break; return v;
  111.   case atDouble:  if(::VarUI1FromR8(dblVal,&v)) break; return v;
  112.   case atCurrency:if(::VarUI1FromCy(cyVal, &v)) break; return v;
  113.   case atDatetime:if(::VarUI1FromDate(date,&v)) break; return v;
  114.   case atString:  if(::VarUI1FromStr(bstrVal,GetLocale(),0L,&v)) break; return v;
  115.   case atObject:  if(::VarUI1FromDisp(pdispVal,GetLocale(),&v)) break; return v;
  116.   case atBool:    return (unsigned char)(boolVal ? 1 : 0);
  117.   case atByRef+atByte:    return *pbVal;
  118.   case atByRef+atShort:   if(::VarUI1FromI2(*piVal,  &v)) break; return v;
  119.   case atByRef+atLong:    if(::VarUI1FromI4(*plVal,  &v)) break; return v;
  120.   case atByRef+atFloat:   if(::VarUI1FromR4(*pfltVal,&v)) break; return v;
  121.   case atByRef+atDouble:  if(::VarUI1FromR8(*pdblVal,&v)) break; return v;
  122.   case atByRef+atCurrency:if(::VarUI1FromCy(*pcyVal, &v)) break; return v;
  123.   case atByRef+atDatetime:if(::VarUI1FromDate(*pdate,&v)) break; return v;
  124.   case atByRef+atString:  if(::VarUI1FromStr(*pbstrVal,GetLocale(),0L,&v)) break; return v;
  125.   case atByRef+atBool:    return (unsigned char)(*pbool ? 1 : 0);
  126.   }
  127.   TXAuto::Raise(TXAuto::xConversionFailure);
  128.   return 0;
  129. }
  130.  
  131. //
  132. //
  133. //
  134. TAutoVal::operator short()
  135. {
  136.   short v;
  137.   switch (vt) {
  138.   case atByte:    return (short)bVal;
  139.   case atShort:   return iVal;
  140.   case atLong:    if(::VarI2FromI4(lVal, &v))  break; return v;
  141.   case atFloat:   if(::VarI2FromR4(fltVal,&v)) break; return v;
  142.   case atDouble:  if(::VarI2FromR8(dblVal,&v)) break; return v;
  143.   case atCurrency:if(::VarI2FromCy(cyVal, &v)) break; return v;
  144.   case atDatetime:if(::VarI2FromDate(date,&v)) break; return v;
  145.   case atString:  if(::VarI2FromStr(bstrVal,GetLocale(),0L,&v)) break; return v;
  146.   case atObject:  if(::VarI2FromDisp(pdispVal,GetLocale(),&v)) break; return v;
  147.   case atBool:    return short(boolVal ? 1 : 0);
  148.   case atByRef+atByte:    return (short)*pbVal;
  149.   case atByRef+atShort:   return *piVal;
  150.   case atByRef+atLong:    if(::VarI2FromI4(*plVal, &v)) break; return v;
  151.   case atByRef+atFloat:   if(::VarI2FromR4(*pfltVal,&v)) break; return v;
  152.   case atByRef+atDouble:  if(::VarI2FromR8(*pdblVal,&v)) break; return v;
  153.   case atByRef+atCurrency:if(::VarI2FromCy(*pcyVal, &v)) break; return v;
  154.   case atByRef+atDatetime:if(::VarI2FromDate(*pdate,&v)) break; return v;
  155.   case atByRef+atString:  if(::VarI2FromStr(*pbstrVal,GetLocale(),0L,&v)) break; return v;
  156.   case atByRef+atBool:    return short(*pbool ? 1 : 0);
  157.   }
  158.   TXAuto::Raise(TXAuto::xConversionFailure);
  159.   return 0;
  160. }
  161.  
  162. //
  163. //
  164. //
  165. TAutoVal::operator long()
  166. {
  167.   long v;
  168.   switch (vt) {
  169.   case atByte:    return (long)bVal;
  170.   case atShort:   return (long)iVal;
  171.   case atLong:    return lVal;
  172.   case atFloat:   if(::VarI4FromR4(fltVal,&v)) break; return v;
  173.   case atDouble:  if(::VarI4FromR8(dblVal,&v)) break; return v;
  174.   case atCurrency:if(::VarI4FromCy(cyVal, &v)) break; return v;
  175.   case atDatetime:if(::VarI4FromDate(date,&v)) break; return v;
  176.   case atString:  if(::VarI4FromStr(bstrVal,GetLocale(),0L,&v)) break; return v;
  177.   case atObject:  if(::VarI4FromDisp(pdispVal,GetLocale(),&v)) break; return v;
  178.   case atBool:    return boolVal ? 1L : 0L;
  179.   case atByRef+atByte:    return (long)*pbVal;
  180.   case atByRef+atShort:   return (long)*piVal;
  181.   case atByRef+atLong:    return *plVal;
  182.   case atByRef+atFloat:   if(::VarI4FromR4(*pfltVal,&v)) break; return v;
  183.   case atByRef+atDouble:  if(::VarI4FromR8(*pdblVal,&v)) break; return v;
  184.   case atByRef+atCurrency:if(::VarI4FromCy(*pcyVal, &v)) break; return v;
  185.   case atByRef+atDatetime:if(::VarI4FromDate(*pdate,&v)) break; return v;
  186.   case atByRef+atString:  if(::VarI4FromStr(*pbstrVal,GetLocale(),0L,&v)) break; return v;
  187.   case atByRef+atBool:    return *pbool ? 1L : 0L;
  188.   }
  189.   TXAuto::Raise(TXAuto::xConversionFailure);
  190.   return 0;
  191. }
  192.  
  193. //
  194. //
  195. //
  196. TAutoVal::operator TBool()
  197. {
  198.   switch (vt) {
  199.   case atByte:    return static_cast<TBool>(bVal != 0);
  200.   case atShort:   return static_cast<TBool>(iVal != 0);
  201.   case atLong:    return static_cast<TBool>(lVal != 0);
  202.   case atFloat:   return static_cast<TBool>(fltVal != 0);
  203.   case atDouble:  return static_cast<TBool>(dblVal != 0);
  204.   case atCurrency:return static_cast<TBool>(cyVal.Lo!=0 || cyVal.Hi != 0);
  205.   case atDatetime:return static_cast<TBool>(date != 0);
  206.   case atString:  {short v; if(::VarBoolFromStr(bstrVal,GetLocale(),0L,&v)) break; return static_cast<TBool>(v!=0);}
  207.   case atObject:  {short v; if(::VarBoolFromDisp(pdispVal,GetLocale(),&v)) break; return static_cast<TBool>(v!=0);}
  208.   case atBool:    return static_cast<TBool>(boolVal != 0);  // note: VARIANT bool TRUE is -1
  209.   case atByRef+atByte:    return static_cast<TBool>(*pbVal != 0);
  210.   case atByRef+atShort:   return static_cast<TBool>(*piVal != 0);
  211.   case atByRef+atLong:    return static_cast<TBool>(*plVal != 0);
  212.   case atByRef+atFloat:   return static_cast<TBool>(*pfltVal != 0);
  213.   case atByRef+atDouble:  return static_cast<TBool>(*pdblVal != 0);
  214.   case atByRef+atCurrency:return static_cast<TBool>(pcyVal->Lo != 0 || pcyVal->Hi != 0);
  215.   case atByRef+atDatetime:return static_cast<TBool>(*pdate != 0);
  216.   case atByRef+atString:  {short v; if(::VarBoolFromStr(*pbstrVal,GetLocale(),0L,&v)) break; return static_cast<TBool>(v!=0);}
  217.   case atByRef+atBool:    return static_cast<TBool>(*pbool != 0);
  218.   }
  219.   TXAuto::Raise(TXAuto::xConversionFailure);
  220.   return 0;
  221. }
  222.  
  223. //
  224. //
  225. //
  226. TAutoVal::operator float()
  227. {
  228.   float v;
  229.   switch (vt) {
  230.   case atByte:     if(::VarR4FromUI1(bVal,&v)) break; return v;
  231.   case atShort:    if(::VarR4FromI2(iVal, &v)) break; return v;
  232.   case atLong:     if(::VarR4FromI4(lVal, &v)) break; return v;
  233.   case atFloat:    return fltVal;
  234.   case atDouble:   if(::VarR4FromR8(dblVal,&v)) break; return v;
  235.   case atCurrency: if(::VarR4FromCy(cyVal, &v)) break; return v;
  236.   case atDatetime: if(::VarR4FromDate(date,&v)) break; return v;
  237.   case atString:   if(::VarR4FromStr(bstrVal,GetLocale(),0L,&v)) break; return v;
  238.   case atObject:   if(::VarR4FromDisp(pdispVal,GetLocale(),&v)) break; return v;
  239.   case atBool:     if(::VarR4FromBool(boolVal,&v)) break; return v;
  240.   case atByRef+atByte:    if(::VarR4FromUI1(*pbVal,&v)) break; return v;
  241.   case atByRef+atShort:   if(::VarR4FromI2(*piVal, &v)) break; return v;
  242.   case atByRef+atLong:    if(::VarR4FromI4(*plVal, &v)) break; return v;
  243.   case atByRef+atFloat:   return *pfltVal;
  244.   case atByRef+atDouble:  if(::VarR4FromR8(*pdblVal,&v)) break; return v;
  245.   case atByRef+atCurrency:if(::VarR4FromCy(*pcyVal, &v)) break; return v;
  246.   case atByRef+atDatetime:if(::VarR4FromDate(*pdate,&v)) break; return v;
  247.   case atByRef+atString:  if(::VarR4FromStr(*pbstrVal,GetLocale(),0L,&v)) break; return v;
  248.   case atByRef+atBool:    if(::VarR4FromBool(*pbool,&v)) break; return v;
  249.   }
  250.   TXAuto::Raise(TXAuto::xConversionFailure);
  251.   return 0;
  252. }
  253.  
  254. //
  255. //
  256. //
  257. TAutoVal::operator double()
  258. {
  259.   double v;
  260.   switch (vt) {
  261.   case atByte:    if(::VarR8FromUI1(bVal,&v)) break; return v;
  262.   case atShort:   if(::VarR8FromI2(iVal, &v)) break; return v;
  263.   case atLong:    if(::VarR8FromI4(lVal, &v)) break; return v;
  264.   case atFloat:   if(::VarR8FromR4(fltVal,&v)) break; return v;
  265.   case atDouble:  return dblVal;
  266.   case atCurrency:if(::VarR8FromCy(cyVal, &v)) break; return v;
  267.   case atDatetime:if(::VarR8FromDate(date,&v)) break; return v;
  268.   case atString:  if(::VarR8FromStr(bstrVal,GetLocale(),0L,&v)) break; return v;
  269.   case atObject:  if(::VarR8FromDisp(pdispVal,GetLocale(),&v)) break; return v;
  270.   case atBool:    if(::VarR8FromBool(boolVal,&v)) break; return v;
  271.   case atByRef+atByte:    if(::VarR8FromUI1(*pbVal,&v)) break; return v;
  272.   case atByRef+atShort:   if(::VarR8FromI2(*piVal, &v)) break; return v;
  273.   case atByRef+atLong:    if(::VarR8FromI4(*plVal, &v)) break; return v;
  274.   case atByRef+atFloat:   if(::VarR8FromR4(*pfltVal,&v)) break; return v;
  275.   case atByRef+atDouble:  return *pdblVal;
  276.   case atByRef+atCurrency:if(::VarR8FromCy(*pcyVal, &v)) break; return v;
  277.   case atByRef+atDatetime:if(::VarR8FromDate(*pdate,&v)) break; return v;
  278.   case atByRef+atString:  if(::VarR8FromStr(*pbstrVal,GetLocale(),0L,&v)) break; return v;
  279.   case atByRef+atBool:    if(::VarR8FromBool(*pbool,&v)) break; return v;
  280.   }
  281.   TXAuto::Raise(TXAuto::xConversionFailure);
  282.   return 0;
  283. }
  284.  
  285. //
  286. //
  287. //
  288. TAutoVal::operator TAutoDate()
  289. {
  290.   DATE v;
  291.   switch (vt) {
  292.   case atByte:     if(::VarDateFromUI1(bVal,&v)) break; return v;
  293.   case atShort:    if(::VarDateFromI2(iVal, &v)) break; return v;
  294.   case atLong:     if(::VarDateFromI4(lVal, &v)) break; return v;
  295.   case atFloat:    if(::VarDateFromR4(fltVal,&v)) break; return v;
  296.   case atDouble:   if(::VarDateFromR8(dblVal,&v)) break; return v;
  297.   case atDatetime: return date;
  298.   case atString:   if(::VarDateFromStr(bstrVal,GetLocale(),0L,&v)) break; return v;
  299.   case atObject:   if(::VarDateFromDisp(pdispVal,GetLocale(),&v)) break; return v;
  300.   case atBool:     if(::VarDateFromBool(boolVal,&v)) break; return v;
  301.   case atByRef+atByte:    if(::VarDateFromUI1(*pbVal,&v)) break; return v;
  302.   case atByRef+atShort:   if(::VarDateFromI2(*piVal, &v)) break; return v;
  303.   case atByRef+atLong:    if(::VarDateFromI4(*plVal, &v)) break; return v;
  304.   case atByRef+atFloat:   if(::VarDateFromR4(*pfltVal,&v)) break; return v;
  305.   case atByRef+atDouble:  if(::VarDateFromR8(*pdblVal,&v)) break; return v;
  306.   case atByRef+atDatetime:return date;
  307.   case atByRef+atString:  if(::VarDateFromStr(*pbstrVal,GetLocale(),0L,&v)) break; return v;
  308.   case atByRef+atBool:    if(::VarDateFromBool(*pbool,&v)) break; return v;
  309.   }
  310.   TXAuto::Raise(TXAuto::xConversionFailure);
  311.   return 0;
  312. }
  313.  
  314. //
  315. //
  316. //
  317. TAutoVal::operator TAutoCurrency()
  318. {
  319.   CY v;
  320.   TAutoCurrency& rv = *(TAutoCurrency*)&v;
  321.  
  322.   HRESULT stat = HR_NOERROR;
  323.   switch (vt) {
  324.   case atByte:     stat = ::VarCyFromUI1(bVal, &v); break;
  325.   case atShort:    stat = ::VarCyFromI2(iVal,  &v); break;
  326.   case atLong:     stat = ::VarCyFromI4(lVal,  &v); break;
  327.   case atFloat:    stat = ::VarCyFromR4(fltVal,&v); break;
  328.   case atDouble:   stat = ::VarCyFromR8(dblVal,&v); break;
  329.   case atCurrency: break;
  330.   case atString:   stat = ::VarCyFromStr(bstrVal,GetLocale(),0L,&v); break;
  331.   case atObject:   stat = ::VarCyFromDisp(pdispVal,GetLocale(),&v); break;
  332.   case atBool:     stat = ::VarCyFromBool(boolVal,&v); break;
  333.   case atByRef+atByte:    stat = ::VarCyFromUI1(*pbVal, &v); break;
  334.   case atByRef+atShort:   stat = ::VarCyFromI2(*piVal,  &v); break;
  335.   case atByRef+atLong:    stat = ::VarCyFromI4(*plVal,  &v); break;
  336.   case atByRef+atFloat:   stat = ::VarCyFromR4(*pfltVal,&v); break;
  337.   case atByRef+atDouble:  stat = ::VarCyFromR8(*pdblVal,&v); break;
  338.   case atByRef+atCurrency:break;
  339.   case atByRef+atString:  stat = ::VarCyFromStr(*pbstrVal,GetLocale(),0L,&v); break;
  340.   case atByRef+atBool:    stat = ::VarCyFromBool(*pbool,&v); break;
  341.   default:         stat = (HRESULT)-1;
  342.   }
  343.   if (stat != HR_NOERROR)
  344.     TXAuto::Raise(TXAuto::xConversionFailure);
  345.   return rv;
  346. }
  347.  
  348. //
  349. // Convert TAutoVal to TUString, used by TAutoString contructor and assignment
  350. //
  351. TAutoVal::operator TUString*()
  352. {
  353.   BSTR v;
  354.   HRESULT stat;
  355. #if defined(BI_PLAT_WIN32)
  356.   LCID lcid = MAKELCID(LangUserDefault, SORT_DEFAULT);
  357. #else
  358.   LCID lcid = MAKELCID(LangUserDefault);
  359. #endif
  360.  
  361.   switch (vt) {
  362.   case atByte:     stat = ::VarBstrFromUI1(bVal, lcid,0, &v); break;
  363.   case atShort:    stat = ::VarBstrFromI2(iVal,  lcid,0, &v); break;
  364.   case atLong:     stat = ::VarBstrFromI4(lVal,  lcid,0, &v); break;
  365.   case atFloat:    stat = ::VarBstrFromR4(fltVal,lcid,0, &v); break;
  366.   case atDouble:   stat = ::VarBstrFromR8(dblVal,lcid,0, &v); break;
  367.   case atCurrency: stat = ::VarBstrFromCy(cyVal ,lcid,0, &v); break;
  368.   case atDatetime: stat = ::VarBstrFromDate(date,lcid,0, &v); break;
  369.   case atString:   if (bstrVal) vt = atLoanedBSTR;
  370.              return (s.Holder=TUString::Create(bstrVal, true, GetLanguage()));
  371.   case atObject:   stat = ::VarBstrFromDisp(pdispVal,GetLocale(),0, &v); break;
  372.   case atBool:     stat = ::VarBstrFromBool(boolVal,lcid,0, &v); break;
  373.   case atByRef+atByte:     stat = ::VarBstrFromUI1(*pbVal, lcid,0, &v); break;
  374.   case atByRef+atShort:    stat = ::VarBstrFromI2(*piVal,  lcid,0, &v); break;
  375.   case atByRef+atLong:     stat = ::VarBstrFromI4(*plVal,  lcid,0, &v); break;
  376.   case atByRef+atFloat:    stat = ::VarBstrFromR4(*pfltVal,lcid,0, &v); break;
  377.   case atByRef+atDouble:   stat = ::VarBstrFromR8(*pdblVal,lcid,0, &v); break;
  378.   case atByRef+atCurrency: stat = ::VarBstrFromCy(*pcyVal ,lcid,0, &v); break;
  379.   case atByRef+atDatetime: stat = ::VarBstrFromDate(*pdate,lcid,0, &v); break;
  380.   case atByRef+atString:   if (*pbstrVal) vt = atByRef+atLoanedBSTR;
  381.            return (s.Holder=TUString::Create(*pbstrVal, true, GetLanguage()));
  382.   case atByRef+atBool:     stat = ::VarBstrFromBool(*pbool,lcid,0,&v);break;
  383.   default:         stat = (HRESULT)-1;
  384.   }
  385.   if (stat != HR_NOERROR)
  386.     TXAuto::Raise(TXAuto::xConversionFailure);
  387.   return TUString::Create(v, false, LANGIDFROMLCID(lcid));
  388. }
  389.  
  390. //
  391. // Convert TAutoVal to string, high performance if already of string type
  392. //
  393. TAutoVal::operator string()
  394. {
  395.   BSTR v;
  396.   HRESULT stat;
  397. #if defined(BI_PLAT_WIN32)
  398.   LCID lcid = MAKELCID(LangUserDefault, SORT_DEFAULT);
  399. #else
  400.   LCID lcid = MAKELCID(LangUserDefault);
  401. #endif
  402.  
  403.   switch (vt) {
  404.   case atByte:     stat = ::VarBstrFromUI1(bVal, lcid,0, &v); break;
  405.   case atShort:    stat = ::VarBstrFromI2(iVal,  lcid,0, &v); break;
  406.   case atLong:     stat = ::VarBstrFromI4(lVal,  lcid,0, &v); break;
  407.   case atFloat:    stat = ::VarBstrFromR4(fltVal,lcid,0, &v); break;
  408.   case atDouble:   stat = ::VarBstrFromR8(dblVal,lcid,0, &v); break;
  409.   case atCurrency: stat = ::VarBstrFromCy(cyVal ,lcid,0, &v); break;
  410.   case atDatetime: stat = ::VarBstrFromDate(date,lcid,0, &v); break;
  411. #if defined(BI_OLECHAR_WIDE)
  412.   case atString:   return string(TString(bstrVal));
  413. #else
  414.   case atString:   return string(bstrVal);
  415. #endif
  416.   case atObject:           stat = ::VarBstrFromDisp(pdispVal,GetLocale(),0, &v); break;
  417.   case atBool:             stat = ::VarBstrFromBool(boolVal,lcid,0, &v); break;
  418.   case atByRef+atByte:     stat = ::VarBstrFromUI1(*pbVal, lcid,0, &v); break;
  419.   case atByRef+atShort:    stat = ::VarBstrFromI2(*piVal,  lcid,0, &v); break;
  420.   case atByRef+atLong:     stat = ::VarBstrFromI4(*plVal,  lcid,0, &v); break;
  421.   case atByRef+atFloat:    stat = ::VarBstrFromR4(*pfltVal,lcid,0, &v); break;
  422.   case atByRef+atDouble:   stat = ::VarBstrFromR8(*pdblVal,lcid,0, &v); break;
  423.   case atByRef+atCurrency: stat = ::VarBstrFromCy(*pcyVal ,lcid,0, &v); break;
  424.   case atByRef+atDatetime: stat = ::VarBstrFromDate(*pdate,lcid,0, &v); break;
  425. #if defined(BI_OLECHAR_WIDE)
  426.   case atByRef+atString:   return string(TString(*pbstrVal));
  427. #else
  428.   case atByRef+atString:   return string(*pbstrVal);
  429. #endif
  430.   case atByRef+atBool:     stat = ::VarBstrFromBool(*pbool,lcid,0,&v); break;
  431.   default:         stat = (HRESULT)-1;
  432.   }
  433.   if (stat != HR_NOERROR)
  434.     TXAuto::Raise(TXAuto::xConversionFailure);
  435. #if defined(BI_OLECHAR_WIDE)
  436.   string s((TString)v);
  437. #else
  438.   string s(v);
  439. #endif
  440.   ::SysFreeString(v);
  441.   return s;
  442. }
  443.  
  444. //
  445. // Convert TAutoVal to TAutoString
  446. //
  447. TAutoVal::operator TAutoString()
  448. {
  449.   TAutoString str( *this );
  450.   return str;
  451. }
  452.  
  453. //
  454. //
  455. //
  456. TAutoVal::operator TString()
  457. {
  458.   return operator string();
  459. }
  460.  
  461. //
  462. //
  463. //
  464. TAutoVal::operator unsigned short()
  465. {
  466.   long temp = operator long();
  467.   if (temp < 0 || temp > long(USHRT_MAX))
  468.     TXAuto::Raise(TXAuto::xConversionFailure);
  469.   return (unsigned short)temp;
  470. }
  471.  
  472. //
  473. // Pointer data type conversion operators
  474. //
  475. TAutoVal::operator unsigned char* ()
  476. {
  477.   ConvRef(atByte);
  478.   return pbVal;
  479. }
  480.  
  481. //
  482. //
  483. TAutoVal::operator short* ()
  484. {
  485.   ConvRef(atShort);
  486.   return piVal;
  487. }
  488.  
  489. //
  490. //
  491. TAutoVal::operator unsigned short* ()
  492. {
  493.   ConvRef(atShort);
  494.   return (unsigned short*)piVal;    // NOTE: May overflow!
  495. }
  496.  
  497. //
  498. //
  499. TAutoVal::operator long* ()
  500. {
  501.   ConvRef(atLong);
  502.   return plVal;
  503. }
  504.  
  505. //
  506. //
  507. TAutoVal::operator unsigned long* ()
  508. {
  509.   ConvRef(atLong);
  510.   return (unsigned long*)plVal;     // NOTE: May overflow!
  511. }
  512.  
  513. //
  514. //
  515. TAutoVal::operator TBool* ()
  516. {
  517.   ConvRef(atBool);
  518.   return (TBool*)pbool;
  519. }
  520.  
  521. //
  522. //
  523. TAutoVal::operator float* ()
  524. {
  525.   ConvRef(atFloat);
  526.   return pfltVal;
  527. }
  528.  
  529. //
  530. //
  531. TAutoVal::operator double* ()
  532. {
  533.   ConvRef(atDouble);
  534.   return pdblVal;
  535. }
  536.  
  537. //
  538. //
  539. TAutoVal::operator TAutoDate* ()
  540. {
  541.   ConvRef(atDatetime);
  542.   return (TAutoDate*)pdate;
  543. }
  544.  
  545. //
  546. //
  547. TAutoVal::operator TAutoCurrency* ()
  548. {
  549.   ConvRef(atCurrency);
  550.   return pcyVal;
  551. }
  552.  
  553. //
  554. //
  555. void TAutoVal::ConvRef(int type)
  556. {
  557. #if 1
  558.   if (vt != (type | atByRef)) {     
  559. #else
  560.   if (type != (vt | atByRef)) {     
  561. #endif
  562.     TXAuto::Raise(TXAuto::xConversionFailure);
  563.   }
  564. }
  565.  
  566. //
  567. //
  568. TAutoVal::operator IDispatch*()
  569. {
  570.   if (vt == atObject) {
  571.     if (pdispVal)
  572.       pdispVal->AddRef();
  573.     return pdispVal;
  574.   }
  575.   if (vt == (atObject | atByRef)) {
  576.     if (*ppdispVal)
  577.       (*ppdispVal)->AddRef();
  578.     return *ppdispVal;
  579.   }
  580.   TXAuto::Raise(TXAuto::xConversionFailure);
  581.   return 0;
  582. }
  583.  
  584. #if defined(BI_PLAT_WIN32)
  585. //
  586. //
  587. //
  588. TAutoVal::operator IPictureDisp*()
  589. {
  590.   return STATIC_CAST(IPictureDisp*, operator IDispatch*());
  591. }
  592.  
  593. //
  594. //
  595. //
  596. TAutoVal::operator IFontDisp*()
  597. {
  598.   return STATIC_CAST(IFontDisp*, operator IDispatch*());
  599. }
  600. #endif
  601.  
  602. //
  603. //
  604. TAutoVal::operator IUnknown*()
  605. {
  606.   if (vt == atUnknown) {
  607.     if (punkVal)
  608.       punkVal->AddRef();
  609.     return punkVal;
  610.   }
  611.   if (vt == (atUnknown | atByRef)) {
  612.     if (*ppunkVal)
  613.       (*ppunkVal)->AddRef();
  614.     return *ppunkVal;
  615.   }
  616.   TXAuto::Raise(TXAuto::xConversionFailure);
  617.   return 0;
  618. }
  619.  
  620. //
  621. //
  622. TAutoVal::operator IUnknown&()
  623. {
  624.   if (vt == atUnknown && punkVal)
  625.     return *punkVal;
  626.   if (vt == (atUnknown | atByRef) && *ppunkVal)
  627.     return **ppunkVal;
  628.   TXAuto::Raise(TXAuto::xConversionFailure);
  629. }
  630.  
  631. //
  632. //
  633. TAutoVal::operator IDispatch&()
  634. {
  635.   if (vt == atObject && pdispVal)
  636.     return *pdispVal;
  637.   if (vt == (atObject | atByRef) && *ppdispVal)
  638.     return **ppdispVal;
  639.   TXAuto::Raise(TXAuto::xConversionFailure);
  640. }
  641.  
  642. #if defined(BI_PLAT_WIN32)
  643. //
  644. //
  645. TAutoVal::operator IPictureDisp&()
  646. {
  647.   return STATIC_CAST(IPictureDisp&, operator IDispatch&());
  648. }
  649.  
  650. //
  651. //
  652. TAutoVal::operator IFontDisp&()
  653. {
  654.   return STATIC_CAST(IFontDisp&, operator IDispatch&());
  655. }
  656. #endif
  657.  
  658. //----------------------------------------------------------------------------
  659. // Localized point to throw a TXAuto exception
  660. //
  661. char*
  662. GetAutoExceptionMsg(TXAuto::TError err)
  663. {
  664.   static TAPointer<char> errMsg = new char[60];
  665.   wsprintf(errMsg, "Automation Exception, TXAuto::ErrorCode=%d", err);
  666.   return errMsg;
  667. }
  668.  
  669. //
  670. //
  671. TXAuto::TXAuto(TXAuto::TError err)
  672.        :TXBase(GetAutoExceptionMsg(err)), ErrorCode(err)
  673. {
  674. }
  675.  
  676. void
  677. TXAuto::Throw()
  678. {
  679.   THROW( *this );
  680. }
  681.  
  682. void
  683. TXAuto::Raise(TXAuto::TError err)
  684. {
  685.   TXAuto(err).Throw();
  686. }
  687.